package com.example.zyl.api.controller;

import cn.hutool.core.date.*;
import cn.hutool.poi.excel.ExcelReader;
import com.example.zyl.api.entity.vo.TimeCardVo;
import com.example.zyl.common.exception.ServiceException;
import com.example.zyl.common.query.annotation.ApiLog;
import com.example.zyl.common.query.enums.BusinessType;
import com.example.zyl.common.utils.ConditionUtils;
import com.example.zyl.common.utils.excel.ExcelUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 考勤卡控制层
 *
 * @author zyl
 * @since 2024-12-02 09:19:27
 */

@RestController
@RequestMapping("timeCard")
@RequiredArgsConstructor
public class TimeCardController {

    /**
     * 下载模板
     */
    @GetMapping(value = "/downloadTemplate")
    @ApiLog(module = "导出考勤卡模板", businessType = BusinessType.EXPORT)
    public void downloadTemplate(HttpServletResponse response) {
        try {
            ExcelUtil.writeExcel(response, this.getMonthList(), "考勤卡模板", "考勤", TimeCardVo.class);
        } catch (Exception e) {
            throw new ServiceException("导出模板失败");
        }
    }


    /**
     * 导入考勤卡
     */
    @GetMapping(value = "/import")
    @ApiLog(module = "导入考勤卡", businessType = BusinessType.IMPORT)
    public void importTimeCard(@RequestParam("file") MultipartFile file) {
        // TODO 导入考勤卡
        try {

            ExcelReader reader = cn.hutool.poi.excel.ExcelUtil.getReader(file.getInputStream());
            String date = reader.readRow(0).stream().map(String::valueOf).findFirst().orElse(null);

            Map<String, Boolean> dateMap = dateMap(date);
            // 读取数据
            List<Map<String, Object>> mapList = reader.read(3, 5, Integer.MAX_VALUE);
            // 过滤数据
            List<Map<String, Object>> collect = mapList.stream()
                    .filter(map -> map.get("姓名").toString().equals("邹阳林"))
                    .collect(Collectors.toList());
            // 转换数据
            Map<String, Map<String, Object>> mapMap = collect.stream().collect(Collectors.toMap(map -> map.get("姓名").toString(), map -> map));
            //本月实际服务天数
            AtomicInteger actualServiceDays = new AtomicInteger(0);
            //未提供服务天数
            AtomicInteger unServiceDays = new AtomicInteger(0);
            //延长服务天数
            AtomicInteger extendDays = new AtomicInteger(0);
            mapMap.forEach((key, value) -> dateMap.forEach((day, v) -> {
                Object o = value.get(day);
                String valueStr = value.getOrDefault(day, "").toString();
                if (null != o && !v && StringUtils.isBlank(valueStr)) {
                    unServiceDays.incrementAndGet();
                }
                if (StringUtils.isNotBlank(valueStr)) {
                    if (v) {
                        extendDays.incrementAndGet();
                    }
                    actualServiceDays.incrementAndGet();
                }
            }));
            // 实际服务天数
            int actualDays = actualServiceDays.get();
            // 未提供服务天数
            int unServiceDaysInt = unServiceDays.get();
            // 延长服务天数
            int extendDaysInt = extendDays.get();

            StringBuilder sb = new StringBuilder();
            sb.append("本月实际服务天数：").append(actualDays).append("天（其中包含延长服务天数").append("\n");
            sb.append("未提供服务天数：").append(unServiceDaysInt).append("天\n");
            sb.append("延长服务天数：").append(extendDaysInt).append("天\n");
            sb.append("调动服务天数：0天，无");
            System.out.println(sb);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 获取日期映射
     *
     * @param date 日期字符串
     * @return Map<String, Boolean>
     */

    public Map<String, Boolean> dateMap(String date) {

        ConditionUtils.throwException(date).accept("统计日期不能为空!");

        String[] split = date.split("：")[1].split("至");

        ConditionUtils.throwException(split[0]).accept("格式不能为空!");
        ConditionUtils.throwException(split[1]).accept("格式不能为空!");

        DateTime begin = DateUtil.parse(split[0].trim());
        DateTime end = DateUtil.parse(split[1].trim());

        // 日期范围
        DateRange range = DateUtil.range(
                DateUtil.beginOfMonth(begin),
                DateUtil.endOfMonth(end),
                DateField.DAY_OF_MONTH
        );
        Map<String, Boolean> dateMap = new LinkedHashMap<>();
        // 日期映射：kry：日期 - value：是否为周末
        range.forEach(dateTime -> {
            boolean isWeekend = false;
            int i = DateUtil.dayOfWeek(dateTime);
            if (i == 1 || i == 7) {
                isWeekend = true;
            }
            int day = dateTime.dayOfMonth();
            dateMap.put(String.valueOf(day), isWeekend);
        });
        return dateMap;
    }


    /**
     * 获取本月的日期列表
     *
     * @return List<String>
     */
    public List<TimeCardVo> getMonthList() {
        // 当前日期
        DateTime now = DateUtil.date();
        AtomicInteger atomicInteger = new AtomicInteger(1);
        // 日期
        List<TimeCardVo> dayTimes = new ArrayList<>();
        // 获取本月的所有日期
        DateUtil.range(
                DateUtil.beginOfMonth(now),
                DateUtil.endOfMonth(now),
                DateField.DAY_OF_MONTH
        ).forEach(date -> {
            String format = DateUtil.format(date, "yyyy-MM-dd");
            TimeCardVo timeCardVo = new TimeCardVo();
            Week week = DateUtil.dayOfWeekEnum(date);
            switch (week) {
                case SUNDAY:
                case SATURDAY:
                    timeCardVo.setCheckStatus("休息");
                    break;
                default:
                    timeCardVo.setCheckStatus("正常");
                    break;
            }
            String chinese = DateUtil.dayOfWeekEnum(date).toChinese();
            timeCardVo.setId(atomicInteger.getAndIncrement());
            timeCardVo.setCheckDate(format);
            timeCardVo.setProjectName("风控项目");
            timeCardVo.setWorkWeek(chinese);
            dayTimes.add(timeCardVo);
        });
        return dayTimes;
    }
}
